package agentService

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"hc_server/pkg/gredis"
	time2 "hc_server/pkg/time"
	"hc_server/routers/models"
	"hc_server/routers/response/merchantResponse"
	"hc_server/routers/service/cache_service"
	"strings"
	"time"
)

type Agent struct {
	Id              int
	TimeType        int         //typed 1=当日 2=昨日 3=本月
	RecommenderCode interface{} //推荐码 代理商编码
	Name            string      // 代理商名称
	Mobile          string      //手机号
	Password        string      //密码 md5
	NPassword       string      //新密码
	AgentNo         string

	Avatar string //头像名称

	InfoType     int //1=今日 2=昨日 3=本月 4=上月 5=历史
	AnalysisType int //1=昨日 2=上周 3=上月
	DynamicType  int //1=昨日 2=上周 3=上月

	AuthStatus int //认证状态
	CreatedAt  string

	BankNo string //结算卡银行卡号
	BankId int    //银行卡id

	PageNum  int
	PageSize int
	Keyword  string
}

// AgentLogin 登录
func (a *Agent) AgentLogin() (map[string]string, error) {
	return models.AgentLogin(a.Mobile, a.Password)
}

// AgentRegister 注册
func (a *Agent) AgentRegister() error {
	//查询此手机号码是否存在
	exist, err := models.AgentBaseAgentIdByMobile(cast.ToString(a.Mobile))
	if err != nil || exist {
		return fmt.Errorf("手机号已存在")
	}

	//换算代理编号
	maxAgentNo := models.AgentGetMaxAgentNo()
	agentNo := fmt.Sprintf("%06d", cast.ToInt(maxAgentNo)+1)

	//查询上级代理商
	superiorsAgent, err := models.AgentGetInfoByAgentNo(a.RecommenderCode)
	if err != nil {
		return err
	}

	//创建代理商，并且返回代理商id
	mapd, err := models.AgentRegister(a.Name, cast.ToString(a.Mobile), agentNo, a.Password, cast.ToInt(superiorsAgent["baseAgentId"]))
	if err != nil {
		return err
	}

	//添加代理商费率基本信息
	err = models.AgentRateAddBaseRateInfo(mapd["id"], superiorsAgent["id"])
	if err != nil {
		return err
	}

	err = models.AgentSettlementRateAddBaseSettlementInfo(mapd["id"], superiorsAgent["id"])
	if err != nil {
		return err
	}

	//获取代理商与上级代理商的关系
	superiorsAgentRelation, err := models.AgentRelationGetInfoByAgentNo(superiorsAgent["id"])
	if err != nil {
		return err
	}

	//将当前代理商id添加到关系中
	superiorsIds := strings.Split(superiorsAgentRelation["relation"], ",")
	superiorsIds = append(superiorsIds, cast.ToString(mapd["id"]))
	relation := strings.Join(superiorsIds, ",")

	//创建代理商与上级代理商的关系
	err = models.AgentRelationAdd(mapd["id"], superiorsAgent["id"], relation, cast.ToInt(superiorsAgent["baseAgentId"]))
	if err != nil {
		return err
	}

	err = models.AgentInfoUpdate(mapd["id"], map[string]interface{}{"agent_relation": relation})
	if err != nil {
		return err
	}

	return nil
}

// AgentMerchantAgentList 商户入驻代理商列表
func (a *Agent) AgentMerchantAgentList() (map[string]interface{}, error) {
	var (
		result, cacheResult map[string]interface{}
	)

	//redis获取数据
	cache := cache_service.Agent{
		ID:       a.Id,
		PageNum:  a.PageNum,
		PageSize: a.PageSize,
		Keyword:  a.Keyword,
	}
	key := cache.GetAgentsKey()
	if gredis.Exists(key) {
		data, err := gredis.Get(key)
		if err != nil {
			logrus.WithError(err).Errorf("获取代理商列表失败:key:%s,err:%v", key, err)
			return nil, errors.New("获取代理商列表失败")
		} else {
			err = json.Unmarshal(data, &cacheResult)
			if err != nil {
				return nil, err
			}
			return cacheResult, nil
		}
	}

	//数据库获取数据
	result, err := models.AgentMerchantAgentList(a.Id, a.PageNum, a.PageSize, a.Keyword)
	if err != nil {
		return nil, err
	}

	err = gredis.Set(key, result, 3600)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// SpecialIndustryMerchantList 特殊行业商户列表
func (a *Agent) SpecialIndustryMerchantList() map[string]interface{} {
	result := make([]*merchantResponse.GetSpecialIndustryMerchantList, 0)
	var condition []string
	condition = append(condition, fmt.Sprintf("agent_id = %d", a.Id))
	condition = append(condition, "industry_status = 1")
	if len(a.Keyword) > 0 {
		condition = append(condition, fmt.Sprintf("(merchant_name LIKE '%%%s%%' OR merchant_no LIKE '%%%s%%')", a.Keyword, a.Keyword))
	}

	return models.MerchantGetMerchantListByMap(strings.Join(condition, " AND "), "id,merchant_name,CONCAT('P',merchant_no) AS merchant_no", a.PageNum, a.PageSize, result)
}

// AgentHome 客户端首页
func (a *Agent) AgentHome() (map[string]interface{}, error) {
	//取出当日交易信息
	info, err := models.GetTransactionDayInfo(a.Id)
	if err != nil {
		return nil, err
	}

	result := models.GetAgentTeamList(a.Id, a.TimeType)
	return map[string]interface{}{
		"amount":       info.Amount,
		"pay_num":      info.PayNum,
		"merchant_num": info.MerchantNum,
		"device_num":   info.DeviceNum,
		"teamList":     result,
	}, nil
}

// AgentData 客户端数据页面
func (a *Agent) AgentData() (any, error) {
	info, err := models.GetAgentPerformanceInfo(a.Id, a.InfoType)
	if err != nil {
		return nil, err
	}

	var timeSql string
	switch a.AnalysisType {
	case 2:
		//上周
		start, end := time2.GetLastWeekDateRange()
		timeSql = fmt.Sprintf("created_at BETWEEN '%s' AND '%s'", start, end)
	case 3:
		//上月
		start, end := time2.GetLastMonthDateRange()
		timeSql = fmt.Sprintf("created_at BETWEEN '%s' AND '%s'", start, end)
	default:
		//昨日
		timeSql = fmt.Sprintf("created_at BETWEEN '%s' AND '%s'", time.Now().AddDate(0, 0, -1).Format("2006-01-02"), time.Now().Format("2006-01-02"))
	}

	//取出当日交易信息
	tran, err := models.GetTransactionTimeTypeInfo(a.Id, timeSql)
	if err != nil {
		return nil, err
	}

	var shopAmount, shopNum, transactionNum string
	if cast.ToInt(tran.MerchantNum) == 0 {
		shopAmount = cast.ToString(0.00)
		shopNum = cast.ToString(0.00)
	} else {
		shopAmount = fmt.Sprintf("%.2f", cast.ToFloat32(tran.Amount)/cast.ToFloat32(tran.MerchantNum))
		shopNum = fmt.Sprintf("%.2f", cast.ToFloat32(tran.PayNum)/cast.ToFloat32(tran.MerchantNum))
	}

	if cast.ToInt(tran.PayNum) == 0 {
		transactionNum = cast.ToString(0.00)
	} else {
		transactionNum = fmt.Sprintf("%.2f", cast.ToFloat32(tran.Amount)/cast.ToFloat32(tran.PayNum))
	}

	var dynamicTime string
	switch a.DynamicType {
	case 2:
		//上周
		start, end := time2.GetLastWeekDateRange()
		dynamicTime = fmt.Sprintf("created_at BETWEEN '%s' AND '%s'", start, end)
	case 3:
		//上月
		start, end := time2.GetLastMonthDateRange()
		dynamicTime = fmt.Sprintf("created_at BETWEEN '%s' AND '%s'", start, end)
	default:
		//昨日
		dynamicTime = fmt.Sprintf("created_at BETWEEN '%s' AND '%s'", time.Now().AddDate(0, 0, -1).Format("2006-01-02"), time.Now().Format("2006-01-02"))
	}
	dynamic := models.GetMerchantOrderDynamicNum(a.Id, dynamicTime)
	var dynamicRate string
	if cast.ToInt(dynamic["merchant_num"]) > 0 {
		dynamicRate = fmt.Sprintf("%.2f", cast.ToFloat32(dynamic["dynamic_num"])/cast.ToFloat32(dynamic["merchant_num"]))
	} else {
		dynamicRate = "0.00"
	}
	return map[string]string{
		"amount":          info.Amount,                           //交易金额
		"pay_num":         info.PayNum,                           //交易笔数
		"merchant_num":    info.MerchantNum,                      //新增商户
		"binding_num":     info.BindingNum,                       //新增绑定
		"agent_num":       info.AgentNum,                         //新增代理商
		"salesman_num":    info.SalesmanNum,                      //新增业务员
		"shop_amount":     shopAmount,                            //店均交易额
		"shop_num":        shopNum,                               //店均笔数
		"transaction_num": transactionNum,                        //交易均笔
		"dynamic_num":     cast.ToString(dynamic["dynamic_num"]), //动态数据
		"dynamic_rate":    dynamicRate,                           //活跃率
	}, err
}

// AgentMyInfo 获取app我的页面
func (a *Agent) AgentMyInfo() (any, error) {
	result, err := models.AgentMyInfo(a.Id)
	if err != nil {
		return nil, err
	}

	balance, err := models.GetAgentBalance(a.Id)
	if err != nil {
		return nil, err
	}
	result.Balance = balance

	return result, nil
}

// MyCenterInfo 获取app我的中心页面
func (a *Agent) MyCenterInfo() (any, error) {
	return models.MyCenterInfo(a.Id)
}

// AgentUploadAvatar 上传头像
func (a *Agent) AgentUploadAvatar() error {
	return models.AgentUploadAvatar(a.Id, a.Avatar)
}

// AgentMyPasswordEdit 修改密码
func (a *Agent) AgentMyPasswordEdit() error {
	return models.AgentMyPasswordEdit(a.Id, a.Password, a.NPassword)
}

// AgentMyInfoDelete 注销账户
func (a *Agent) AgentMyInfoDelete() error {
	return models.AgentMyInfoDelete(a.Id)
}

// AgentBindSettlementCard 绑定结算卡
func (a *Agent) AgentBindSettlementCard() error {
	return models.BankAdd(&models.AgentSettlementBank{
		No:      a.BankNo,
		BankId:  a.BankId,
		AgentId: a.Id,
	})
}
